libxl: Fix leaks on context init failure
authorIan Jackson <ian.jackson@eu.citrix.com>
Fri, 13 Jan 2012 16:54:27 +0000 (16:54 +0000)
committerIan Jackson <ian.jackson@eu.citrix.com>
Fri, 13 Jan 2012 16:54:27 +0000 (16:54 +0000)
Several of the error exits from libxl_ctx_alloc leaked the context
struct itself and sometimes other resources too.

Fix this by using the standard "rc = ERROR_FOO; goto out" error
handling style throughout.

Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
Committed-by: Ian Jackson <Ian.Jackson@eu.citrix.com>
tools/libxl/libxl.c

index 6e3c5a872dbdc36889c1d07a572fb924ee0d3f37..169fc97781f99db742d0c3f31ec442148d6e0de1 100644 (file)
 int libxl_ctx_alloc(libxl_ctx **pctx, int version,
                     unsigned flags, xentoollog_logger * lg)
 {
-    libxl_ctx *ctx;
+    libxl_ctx *ctx = NULL;
     struct stat stat_buf;
     const pthread_mutex_t mutex_value = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
+    int rc;
 
-    if (version != LIBXL_VERSION)
-        return ERROR_VERSION;
+    if (version != LIBXL_VERSION) { rc = ERROR_VERSION; goto out; }
 
     ctx = malloc(sizeof(*ctx));
     if (!ctx) {
         LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "Failed to allocate context\n");
-        return ERROR_NOMEM;
+        rc = ERROR_NOMEM; goto out;
     }
 
     memset(ctx, 0, sizeof(libxl_ctx));
@@ -48,14 +48,14 @@ int libxl_ctx_alloc(libxl_ctx **pctx, int version,
     if ( stat(XENSTORE_PID_FILE, &stat_buf) != 0 ) {
         LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "Is xenstore daemon running?\n"
                      "failed to stat %s", XENSTORE_PID_FILE);
-        return ERROR_FAIL;
+        rc = ERROR_FAIL; goto out;
     }
 
     ctx->xch = xc_interface_open(lg,lg,0);
     if (!ctx->xch) {
         LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, errno,
                         "cannot open libxc handle");
-        return ERROR_FAIL;
+        rc = ERROR_FAIL; goto out;
     }
 
     ctx->xsh = xs_daemon_open();
@@ -64,12 +64,16 @@ int libxl_ctx_alloc(libxl_ctx **pctx, int version,
     if (!ctx->xsh) {
         LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, errno,
                         "cannot connect to xenstore");
-        xc_interface_close(ctx->xch);
-        return ERROR_FAIL;
+        rc = ERROR_FAIL; goto out;
     }
 
     *pctx = ctx;
     return 0;
+
+ out:
+    libxl_ctx_free(ctx);
+    *pctx = NULL;
+    return rc;
 }
 
 int libxl_ctx_free(libxl_ctx *ctx)